package loganalyzer

import (
	"bufio"
	"encoding/json"
	"fmt"
	"os"
	"regexp"
	"sort"
	"strings"
	"time"
)

// LogEntry 日志条目
type LogEntry struct {
	Timestamp time.Time         `json:"timestamp"`
	Level     string           `json:"level"`
	Message   string           `json:"message"`
	Fields    map[string]string `json:"fields"`
}

// LogAnalyzer 日志分析器
type LogAnalyzer struct {
	patterns map[string]*regexp.Regexp
	entries  []LogEntry
}

// NewLogAnalyzer 创建日志分析器
func NewLogAnalyzer() *LogAnalyzer {
	return &LogAnalyzer{
		patterns: make(map[string]*regexp.Regexp),
		entries:  make([]LogEntry, 0),
	}
}

// AddPattern 添加匹配模式
func (a *LogAnalyzer) AddPattern(name, pattern string) error {
	re, err := regexp.Compile(pattern)
	if err != nil {
		return err
	}
	a.patterns[name] = re
	return nil
}

// ParseFile 解析日志文件
func (a *LogAnalyzer) ParseFile(filename string) error {
	file, err := os.Open(filename)
	if err != nil {
		return err
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line := scanner.Text()
		entry, err := a.parseLine(line)
		if err != nil {
			continue
		}
		a.entries = append(a.entries, entry)
	}

	return scanner.Err()
}

// parseLine 解析单行日志
func (a *LogAnalyzer) parseLine(line string) (LogEntry, error) {
	var entry LogEntry
	entry.Fields = make(map[string]string)

	// 尝试解析JSON格式
	if strings.HasPrefix(line, "{") {
		err := json.Unmarshal([]byte(line), &entry)
		if err == nil {
			return entry, nil
		}
	}

	// 使用正则表达式匹配
	for name, pattern := range a.patterns {
		matches := pattern.FindStringSubmatch(line)
		if matches != nil {
			entry.Fields[name] = matches[1]
		}
	}

	return entry, nil
}

// Analyze 分析日志
func (a *LogAnalyzer) Analyze() *AnalysisResult {
	result := &AnalysisResult{
		ErrorCount:   make(map[string]int),
		StatusCodes:  make(map[int]int),
		ResponseTime: make(map[string][]float64),
	}

	for _, entry := range a.entries {
		// 统计错误
		if entry.Level == "error" {
			result.ErrorCount[entry.Message]++
		}

		// 统计状态码
		if status, ok := entry.Fields["status"]; ok {
			var code int
			if _, err := fmt.Sscanf(status, "%d", &code); err == nil {
				result.StatusCodes[code]++
			}
		}

		// 统计响应时间
		if latency, ok := entry.Fields["latency"]; ok {
			if duration, err := time.ParseDuration(latency); err == nil {
				path := entry.Fields["path"]
				result.ResponseTime[path] = append(result.ResponseTime[path], float64(duration.Milliseconds()))
			}
		}
	}

	return result
}

// AnalysisResult 分析结果
type AnalysisResult struct {
	ErrorCount   map[string]int       // 错误统计
	StatusCodes  map[int]int         // 状态码统计
	ResponseTime map[string][]float64 // 响应时间统计
}

// GenerateReport 生成报告
func (r *AnalysisResult) GenerateReport() string {
	var report strings.Builder

	// 错误统计报告
	report.WriteString("=== 错误统计 ===\n")
	for err, count := range r.ErrorCount {
		report.WriteString(fmt.Sprintf("%s: %d\n", err, count))
	}

	// 状态码统计报告
	report.WriteString("\n=== 状态码统计 ===\n")
	for code, count := range r.StatusCodes {
		report.WriteString(fmt.Sprintf("%d: %d\n", code, count))
	}

	// 响应时间统计报告
	report.WriteString("\n=== 响应时间统计 ===\n")
	for path, times := range r.ResponseTime {
		avg := calculateAverage(times)
		p95 := calculatePercentile(times, 95)
		p99 := calculatePercentile(times, 99)
		report.WriteString(fmt.Sprintf("%s:\n", path))
		report.WriteString(fmt.Sprintf("  平均: %.2fms\n", avg))
		report.WriteString(fmt.Sprintf("  P95: %.2fms\n", p95))
		report.WriteString(fmt.Sprintf("  P99: %.2fms\n", p99))
	}

	return report.String()
}

func calculateAverage(numbers []float64) float64 {
	if len(numbers) == 0 {
		return 0
	}
	sum := 0.0
	for _, n := range numbers {
		sum += n
	}
	return sum / float64(len(numbers))
}

func calculatePercentile(numbers []float64, percentile float64) float64 {
	if len(numbers) == 0 {
		return 0
	}
	sorted := make([]float64, len(numbers))
	copy(sorted, numbers)
	sort.Float64s(sorted)
	index := int(float64(len(sorted)-1) * percentile / 100)
	return sorted[index]
} 